<!--
 *  Copyright (c) Facebook, Inc.
 *  All rights reserved.
 *
 *  This source code is licensed under the license found in the
 *  LICENSE file in the root directory of this source tree.
-->
<!DOCTYPE html>
<html>
  <head>
    <style>
      body {
        height: 100%;
        margin: 0;
        width: 100%;
        overflow: hidden;
      }
      #graphiql {
        height: 100vh;
      }
    </style>
    <!--
      This GraphiQL example depends on Promise and fetch, which are available in
      modern browsers, but can be "polyfilled" for older browsers.
      GraphiQL itself depends on React DOM.
      If you do not want to rely on a CDN, you can host these files locally or
      include them directly in your favored resource bunder.
    -->
    <link
      href="//cdn.jsdelivr.net/npm/graphiql@0.12.0/graphiql.css"
      rel="stylesheet"
    />
    <script src="//cdn.jsdelivr.net/npm/whatwg-fetch@2.0.3/fetch.min.js"></script>
    <script src="//cdn.jsdelivr.net/npm/react@16.2.0/umd/react.production.min.js"></script>
    <script src="//cdn.jsdelivr.net/npm/react-dom@16.2.0/umd/react-dom.production.min.js"></script>
    <script src="//cdn.jsdelivr.net/npm/graphiql@0.12.0/graphiql.min.js"></script>
    <script src="//cdn.jsdelivr.net/npm/subscriptions-transport-ws@0.7.0/browser/client.js"></script>
    <script src="//cdn.jsdelivr.net/npm/graphiql-subscriptions-fetcher@0.0.2/browser/client.js"></script>
  </head>
  <body>
    <div id="graphiql">Loading...</div>
    <script>
      // Inject default values from Python.
      var defaultQuery = `${default_query}`;
      var defaultVariables = `${default_variables}`;
      var defaultHeaders = `${default_headers}`;
      var subscriptionsEndpoint = `${subscriptions_endpoint}`;
      var graphQLEndpoint = `${endpoint}`;

      // Parse the search string to get url parameters.
      var search = window.location.search;
      var parameters = {};
      search
        .substr(1)
        .split("&")
        .forEach(function(entry) {
          var eq = entry.indexOf("=");
          if (eq >= 0) {
            parameters[
              decodeURIComponent(entry.slice(0, eq))
            ] = decodeURIComponent(entry.slice(eq + 1));
          }
        });

      if (!parameters.variables && defaultVariables !== "") {
        parameters.variables = defaultVariables;
      }

      // if variables was provided, try to format it.
      if (parameters.variables) {
        try {
          parameters.variables = JSON.stringify(
            JSON.parse(parameters.variables),
            null,
            2
          );
        } catch (e) {
          // Do nothing, we want to display the invalid JSON as a string, rather
          // than present an error.
        }
      }

      if (!parameters.query && defaultQuery !== "") {
        parameters.query = defaultQuery;
      }

      // When the query and variables string is edited, update the URL bar so
      // that it can be easily shared
      function onEditQuery(newQuery) {
        parameters.query = newQuery;
        updateURL();
      }
      function onEditVariables(newVariables) {
        parameters.variables = newVariables;
        updateURL();
      }
      function onEditOperationName(newOperationName) {
        parameters.operationName = newOperationName;
        updateURL();
      }
      function updateURL() {
        var newSearch =
          "?" +
          Object.keys(parameters)
            .filter(function(key) {
              return Boolean(parameters[key]);
            })
            .map(function(key) {
              return (
                encodeURIComponent(key) +
                "=" +
                encodeURIComponent(parameters[key])
              );
            })
            .join("&");
        history.replaceState(null, null, newSearch);
      }

      function graphQLFetcher(graphQLParams) {
        return fetch(graphQLEndpoint, {
          method: "post",
          headers: Object.assign(JSON.parse(defaultHeaders), {
            Accept: "application/json",
            "Content-Type": "application/json"
          }),
          body: JSON.stringify(graphQLParams),
          credentials: "include"
        })
          .then(function(response) {
            return response.text();
          })
          .then(function(responseBody) {
            try {
              return JSON.parse(responseBody);
            } catch (error) {
              return responseBody;
            }
          });
      }

      if (!subscriptionsEndpoint) {
        parameters.fetcher = graphQLFetcher;
      } else {
        var subscriptionsURL = [
          window.location.protocol === "https:" ? "wss://" : "ws://",
          window.location.hostname,
          window.location.port ? ":" + window.location.port : "",
          subscriptionsEndpoint
        ].join("");

        var subscriptionsClient = new window.SubscriptionsTransportWs.SubscriptionClient(
          subscriptionsURL,
          { reconnect: true }
        );

        parameters.fetcher = window.GraphiQLSubscriptionsFetcher.graphQLFetcher(
          subscriptionsClient,
          graphQLFetcher
        );
      }

      ReactDOM.render(
        React.createElement(GraphiQL, {
          fetcher: parameters.fetcher,
          query: parameters.query,
          variables: parameters.variables,
          operationName: parameters.operationName,
          onEditQuery: onEditQuery,
          onEditVariables: onEditVariables,
          onEditOperationName: onEditOperationName
        }),
        document.getElementById("graphiql")
      );
    </script>
  </body>
</html>
